home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / WINDOW.C < prev    next >
C/C++ Source or Header  |  1993-05-20  |  11KB  |  460 lines

  1. #include "jam.h"
  2. #include"stdlib.h"
  3. /*
  4.  *        Window handling.
  5.  */
  6. #include    "def.h"
  7. #include "keyname.h"
  8.  
  9. static char *only1window = "Only 1 window.";
  10. /*
  11.  * Reposition dot in the current
  12.  * window to line "n". If the argument is
  13.  * positive, it is that line. If it is negative it
  14.  * is that line from the bottom. If it is 0 the window
  15.  * is centered (this is what the standard redisplay code
  16.  * does).  If GOSREC is undefined, default is 0, so it acts like GNU.
  17.  * If GOSREC is defined, with no argument it defaults to 1
  18.  * and works like in Gosling.
  19.  */
  20. /*ARGSUSED*/
  21. reposition(f, n)
  22. int f, n;
  23. {
  24. #ifndef GOSREC
  25.   curwp->w_force = (char)((f & FFARG) ? (n>=0 ? n+1 : n) : 0);
  26. #else
  27.   curwp->w_force = n;
  28. #endif
  29.   curwp->w_flag |= WFFORCE;
  30.   sgarbf = TRUE;
  31.   return TRUE;
  32. }
  33.  
  34. /*
  35.  * Refresh the display. A call is made to the
  36.  * "ttresize" entry in the terminal handler, which tries
  37.  * to reset "nrow" and "ncol". They will, however, never
  38.  * be set outside of the NROW or NCOL range. If the display
  39.  * changed size, arrange that everything is redone, then
  40.  * call "update" to fix the display. We do this so the
  41.  * new size can be displayed. In the normal case the
  42.  * call to "update" in "main.c" refreshes the screen,
  43.  * and all of the windows need not be recomputed.
  44.  * Note that when you get to the "display unusable"
  45.  * message, the screen will be messed up. If you make
  46.  * the window bigger again, and send another command,
  47.  * everything will get fixed. Hopefully!
  48.  */
  49. /*ARGSUSED*/
  50. myrefresh(f, n)
  51. int f, n;
  52. {
  53.   register EWINDOW *wp;
  54.   register int    oldnrow;
  55.   register int    oldncol;
  56.   
  57.   oldnrow = nrow;
  58.   oldncol = ncol;
  59. #ifdef WINDOWED
  60.   WindowErase();    /* only called for case of resize, so force this! */
  61.   oldnrow = -1;        /* hack */
  62. #endif
  63.   ttresize();
  64.   if (nrow!=oldnrow || ncol!=oldncol) 
  65.     {
  66.       wp = wheadp;            /* Find last.        */
  67.       while (wp->w_wndp != NULL)
  68.     wp = wp->w_wndp;
  69.       if (nrow < wp->w_toprow+3)    /* Check if too small.    */ 
  70.     { 
  71. #ifdef WINDOWED
  72.           WindowMessage("Some window too small.", FALSE);
  73. #else
  74.       ewprintf("Display unusable");
  75. #endif
  76.       return (FALSE);
  77.     }
  78.       wp->w_ntrows = (char)(nrow-wp->w_toprow-2);
  79.       sgarbf = TRUE;
  80.       update();
  81.       ewprintf("New size %d by %d", nrow, ncol);
  82.     }
  83.   else
  84.     sgarbf = TRUE;
  85.   return TRUE;
  86. }
  87.  
  88. /*
  89.  * The command to make the next
  90.  * window (next => down the screen)
  91.  * the current window. There are no real
  92.  * errors, although the command does
  93.  * nothing if there is only 1 window on
  94.  * the screen.
  95.  */
  96. /*ARGSUSED*/
  97. nextwind(f, n)
  98. int f, n;
  99. {
  100.   register EWINDOW *wp;
  101.   
  102.   if (wheadp->w_wndp == NULL)       /* feeback-for-user check */
  103.     ewprintf(only1window);
  104.   if ((wp=curwp->w_wndp) == NULL)
  105.     wp = wheadp;
  106.   curwp = wp;
  107.   curbp = wp->w_bufp;
  108.   return TRUE;
  109. }
  110.  
  111. #ifdef    GOSMACS
  112. /* not in Gnu Emacs */
  113. /*
  114.  * This command makes the previous
  115.  * window (previous => up the screen) the
  116.  * current window. There arn't any errors,
  117.  * although the command does not do a lot
  118.  * if there is 1 window.
  119.  */
  120. /*ARGSUSED*/
  121. prevwind(f, n)
  122. int f, n;
  123. {
  124.   register EWINDOW *wp1;
  125.   register EWINDOW *wp2;
  126.   
  127.   if (wheadp->w_wndp == NULL)       /* feeback-for-user check */
  128.     ewprintf(only1window);
  129.   wp1 = wheadp;
  130.   wp2 = curwp;
  131.   if (wp1 == wp2)
  132.     wp2 = NULL;
  133.   while (wp1->w_wndp != wp2)
  134.     wp1 = wp1->w_wndp;
  135.   curwp = wp1;
  136.   curbp = wp1->w_bufp;
  137.   return TRUE;
  138. }
  139. #endif
  140.  
  141. /*
  142.  * This command makes the current
  143.  * window the only window on the screen.
  144.  * Try to set the framing
  145.  * so that "." does not have to move on
  146.  * the display. Some care has to be taken
  147.  * to keep the values of dot and mark
  148.  * in the buffer structures right if the
  149.  * distruction of a window makes a buffer
  150.  * become undisplayed.
  151.  */
  152. /*ARGSUSED*/
  153. onlywind(f, n)
  154. int f, n;
  155. {
  156.   register EWINDOW *wp;
  157.   register LINE    *lp;
  158.   register int    i;
  159.   
  160.   while (wheadp != curwp) 
  161.     {
  162.       wp = wheadp;
  163.       wheadp = wp->w_wndp;
  164.       if (--wp->w_bufp->b_nwnd == 0) 
  165.     {
  166.       wp->w_bufp->b_dotp  = wp->w_dotp;
  167.       wp->w_bufp->b_doto  = wp->w_doto;
  168.       wp->w_bufp->b_markp = wp->w_markp;
  169.       wp->w_bufp->b_marko = wp->w_marko;
  170.     }
  171.       free((char *) wp);
  172.     }
  173.   while (curwp->w_wndp != NULL) 
  174.     {
  175.       wp = curwp->w_wndp;
  176.       curwp->w_wndp = wp->w_wndp;
  177.       if (--wp->w_bufp->b_nwnd == 0) 
  178.     {
  179.       wp->w_bufp->b_dotp  = wp->w_dotp;
  180.       wp->w_bufp->b_doto  = wp->w_doto;
  181.       wp->w_bufp->b_markp = wp->w_markp;
  182.       wp->w_bufp->b_marko = wp->w_marko;
  183.     }
  184.       free((char *) wp);
  185.     }
  186.   lp = curwp->w_linep;
  187.   i  = curwp->w_toprow;
  188.   while (i!=0 && lback(lp)!=curbp->b_linep) 
  189.     {
  190.       --i;
  191.       lp = lback(lp);
  192.     }
  193.   curwp->w_toprow = 0;
  194.   curwp->w_ntrows = (char)(nrow-2);        /* 2 = mode, echo.    */
  195.   curwp->w_linep    = lp;
  196.   curwp->w_flag  |= WFMODE|WFHARD;
  197.   return TRUE;
  198. }
  199.  
  200. /*
  201.  * Split the current window. A window
  202.  * smaller than 3 lines cannot be split.
  203.  * The only other error that is possible is
  204.  * a "malloc" failure allocating the structure
  205.  * for the new window.
  206.  */
  207. /*ARGSUSED*/
  208. splitwind(f, n)
  209. int f, n;
  210. {
  211.   register EWINDOW *wp;
  212.   register LINE    *lp;
  213.   register int    ntru;
  214.   register int    ntrd;
  215.   int        ntrl;
  216.   EWINDOW    *wp1, *wp2;
  217.   
  218.   if (curwp->w_ntrows < 3) 
  219.     {
  220.       ewprintf("Cannot split a %d line window", curwp->w_ntrows);
  221.       return (FALSE);
  222.     }
  223.   if ((wp = (EWINDOW *)calloc(1, sizeof(EWINDOW))) == NULL) 
  224.     {
  225.       ewprintf(Nobytes, sizeof(EWINDOW));
  226.       return (FALSE);
  227.     }
  228.   curbp->b_nwnd++;            /* Displayed yet again    */
  229.   wp->w_bufp  = curwp->w_bufp; /*curbp;*/
  230.   wp->w_dotp  = curwp->w_dotp;
  231.   wp->w_doto  = curwp->w_doto;
  232.   wp->w_markp = curwp->w_markp;
  233.   wp->w_marko = curwp->w_marko;
  234.   ntru = (curwp->w_ntrows-1) / 2;        /* Upper size        */
  235.   ntrl = (curwp->w_ntrows-1) - ntru;        /* Lower size        */
  236.   lp = curwp->w_linep;
  237.   ntrd = 0;
  238.   while (lp != curwp->w_dotp) 
  239.     {
  240.       ++ntrd;
  241.       lp = lforw(lp);
  242.     }
  243.   lp = curwp->w_linep;
  244.   if (ntrd <= ntru)            /* Old is upper window. */ 
  245.     {
  246.       if (ntrd == ntru)                /* Hit mode line.    */
  247.     lp = lforw(lp);
  248.       curwp->w_ntrows = (char)ntru;
  249.       wp->w_wndp = curwp->w_wndp;
  250.       curwp->w_wndp = wp;
  251.       wp->w_toprow = (char)(curwp->w_toprow+ntru+1);
  252.       wp->w_ntrows = (char)ntrl;
  253.     }
  254.   else                 /* Old is lower window    */
  255.     {
  256.       wp1 = NULL;
  257.       wp2 = wheadp;
  258.       while (wp2 != curwp) 
  259.     {
  260.       wp1 = wp2;
  261.       wp2 = wp2->w_wndp;
  262.     }
  263.       if (wp1 == NULL)
  264.     wheadp = wp;
  265.       else
  266.     wp1->w_wndp = wp;
  267.       wp->w_wndp   = curwp;
  268.       wp->w_toprow = curwp->w_toprow;
  269.       wp->w_ntrows = (char)ntru++;    /* Mode line.        */
  270.       curwp->w_toprow += ntru;
  271.       curwp->w_ntrows = (char)ntrl;
  272.       while (ntru--)
  273.     lp = lforw(lp);
  274.     }
  275.   curwp->w_linep = lp;            /* Adjust the top lines */
  276.   wp->w_linep = lp;            /* if necessary.    */
  277.   curwp->w_flag |= WFMODE|WFHARD;
  278.   wp->w_flag |= WFMODE|WFHARD;
  279.   return TRUE;
  280. }
  281.  
  282. /*
  283.  * Enlarge the current window.
  284.  * Find the window that loses space. Make
  285.  * sure it is big enough. If so, hack the window
  286.  * descriptions, and ask redisplay to do all the
  287.  * hard work. You don't just set "force reframe"
  288.  * because dot would move.
  289.  */
  290. /*ARGSUSED*/
  291. enlargewind(f, n)
  292. int f, n;
  293. {
  294.   register EWINDOW *adjwp;
  295.   register LINE    *lp;
  296.   register int    i;
  297.   
  298.   if (n < 0)
  299.     return shrinkwind(f, -n);
  300.   if (wheadp->w_wndp == NULL) 
  301.     {
  302.       ewprintf(only1window);
  303.       return FALSE;
  304.     }
  305.   if ((adjwp=curwp->w_wndp) == NULL) 
  306.     {
  307.       adjwp = wheadp;
  308.       while (adjwp->w_wndp != curwp)
  309.     adjwp = adjwp->w_wndp;
  310.     }
  311.   if (adjwp->w_ntrows <= (char)n) 
  312.     {
  313.       ewprintf(Impossible);
  314.       return FALSE;
  315.     }
  316.   if (curwp->w_wndp == adjwp) 
  317.     {        /* Shrink below.    */
  318.       lp = adjwp->w_linep;
  319.       for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  320.     lp = lforw(lp);
  321.       adjwp->w_linep    = lp;
  322.       adjwp->w_toprow += n;
  323.     }
  324.   else                /* Shrink above.    */ 
  325.     {
  326.       lp = curwp->w_linep;
  327.       for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  328.     lp = lback(lp);
  329.       curwp->w_linep    = lp;
  330.       curwp->w_toprow -= n;
  331.     }
  332.   curwp->w_ntrows += n;
  333.   adjwp->w_ntrows -= n;
  334.   curwp->w_flag |= WFMODE|WFHARD;
  335.   adjwp->w_flag |= WFMODE|WFHARD;
  336.   return TRUE;
  337. }
  338.  
  339. /*
  340.  * Shrink the current window.
  341.  * Find the window that gains space. Hack at
  342.  * the window descriptions. Ask the redisplay to
  343.  * do all the hard work.
  344.  */
  345. shrinkwind(f, n)
  346. int f, n;
  347. {
  348.   register EWINDOW *adjwp;
  349.   register LINE    *lp;
  350.   register int    i;
  351.   
  352.   if (n < 0)
  353.     return enlargewind(f, -n);
  354.   if (wheadp->w_wndp == NULL) 
  355.     {
  356.       ewprintf(only1window);
  357.       return FALSE;
  358.     }
  359.   /*
  360.    * Bit of flakiness - KRANDOM means it was an internal call, and
  361.    * to be trusted implicitly about sizes.
  362.    */
  363.   if ( !(f & FFRAND) && curwp->w_ntrows <= (char)n) 
  364.     {
  365.       ewprintf(Impossible);
  366.       return (FALSE);
  367.     }
  368.   if ((adjwp=curwp->w_wndp) == NULL) 
  369.     {
  370.       adjwp = wheadp;
  371.       while (adjwp->w_wndp != curwp)
  372.     adjwp = adjwp->w_wndp;
  373.     }
  374.   if (curwp->w_wndp == adjwp)    /* Grow below.        */ 
  375.     {    
  376.       lp = adjwp->w_linep;
  377.       for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  378.     lp = lback(lp);
  379.       adjwp->w_linep    = lp;
  380.       adjwp->w_toprow -= n;
  381.     } 
  382.   else 
  383.     {                /* Grow above.        */
  384.       lp = curwp->w_linep;
  385.       for (i=0; i<n && lp!=curbp->b_linep; ++i)
  386.     lp = lforw(lp);
  387.       curwp->w_linep    = lp;
  388.       curwp->w_toprow += n;
  389.     }
  390.   curwp->w_ntrows -= n;
  391.   adjwp->w_ntrows += n;
  392.   curwp->w_flag |= WFMODE|WFHARD;
  393.   adjwp->w_flag |= WFMODE|WFHARD;
  394.   return (TRUE);
  395. }
  396.  
  397. /*
  398.  * Delete current window. Call shrink-window to do the screen
  399.  * updating, then throw away the window.
  400.  */
  401. /*ARGSUSED*/
  402. delwind(f, n)
  403. int f, n;
  404. {
  405.   register EWINDOW *wp, *nwp;
  406.   
  407.   wp = curwp;        /* Cheap...        */
  408.                     /* shrinkwind returning false means only one window... */
  409.  
  410.   if (shrinkwind(FFRAND, wp->w_ntrows + 1) == FALSE)
  411.     return FALSE;
  412.  
  413.   wp->w_bufp->b_nwnd--;
  414.   if (wp->w_bufp->b_nwnd == 0) 
  415.     {
  416.       wp->w_bufp->b_dotp  = wp->w_dotp;
  417.       wp->w_bufp->b_doto  = wp->w_doto;
  418.       wp->w_bufp->b_markp = wp->w_markp;
  419.       wp->w_bufp->b_marko = wp->w_marko;
  420.     }
  421.  
  422.   /* since shrinkwind did't crap out, we know we have a second window 
  423.    */
  424.   if (wp == wheadp) 
  425.     wheadp = curwp = wp->w_wndp;          /* deleting first */
  426.   else if ((curwp = wp->w_wndp) == NULL) 
  427.     curwp = wheadp;                       /* deleting last */
  428.   curbp = curwp->w_bufp;
  429.  
  430.   for (nwp = wheadp; nwp != NULL; nwp = nwp->w_wndp)
  431.     if (nwp->w_wndp == wp)
  432.       {
  433.     nwp->w_wndp = wp->w_wndp;
  434.     break ;
  435.       }
  436.   free((char *) wp);
  437.   return TRUE;
  438. }
  439. /*
  440.  * Pick a window for a pop-up.
  441.  * Split the screen if there is only
  442.  * one window. Pick the uppermost window that
  443.  * isn't the current window. An LRU algorithm
  444.  * might be better. Return a pointer, or
  445.  * NULL on error.
  446.  */
  447. EWINDOW    *wpopup() 
  448. {
  449.   register EWINDOW *wp;
  450.   
  451.   if (wheadp->w_wndp == NULL
  452.       && splitwind(FFRAND, 0) == FALSE)
  453.     return NULL;
  454.   wp = wheadp;                /* Find window to use    */
  455.   while (wp!=NULL && wp==curwp)
  456.     wp = wp->w_wndp;
  457.   return wp;
  458. }
  459.  
  460.